/**
 * Created on May 9, 2007
 */
package jvs.vfs;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URI;

import jvs.vfs.util.Log;

/**
 * @author qiangli
 *
 */

public abstract class IFileBaseImpl implements IFile {
	protected final static int BUFSIZE = 1024;

	protected URI uri = null;
	
	protected IFileBaseImpl() {
	}
	
	public IFileBaseImpl(URI uri) {
		this.uri = uri;
		
		trace(uri);
	}

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#canRead()
	 */
	public boolean canRead() {
		return true;
	}

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#canWrite()
	 */
	public boolean canWrite() {
		return true;
	}

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#copy(java.net.URI)
	 */
	public boolean copy(URI uri) {
		java.io.InputStream in;
		try {
			in = getInputStream();
			OutputStream out = uri.toURL().openConnection().getOutputStream();
			byte buf[] = new byte[BUFSIZE];
			int len;
			while ((len = in.read(buf, 0, BUFSIZE)) != -1) {
				out.write(buf, 0, len);
			}
			in.close();
			out.close();
			return true;
		} catch (Exception e) {
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#create()
	 */
	abstract public boolean create();
	
	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#delete()
	 */
	abstract public boolean delete();

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#exists()
	 */
	abstract public boolean exists();
	
	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#getAttribute(java.lang.String)
	 */
	public Object getAttribute(String name) {
		return null;
	}

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#getContent()
	 */
	public String getContent() {
		try {
			InputStream in = getInputStream();
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			byte buf[] = new byte[BUFSIZE];
			int len;
			while ((len = in.read(buf, 0, BUFSIZE)) != -1) {
				out.write(buf, 0, len);
			}
			in.close();
			out.close();
			return out.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#getContentEncoding()
	 */
	public String getContentEncoding() {
		return null;
	}

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#getContentType()
	 */
	public String getContentType() {
		return null;
	}

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#getInputStream()
	 */
	public abstract InputStream getInputStream();

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#getLastModified()
	 */
	public long getLastModified() {
		return 0;
	}

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#getLength()
	 */
	public long getLength() {
		InputStream in = getInputStream();
		if (in == null) {
			return -1;
		}
		try {
			return count(in);
		} catch (IOException e) {
		} finally {
			try {
				in.close();
			} catch (IOException e) {
			}
		}
		return -1;
	}
	
	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#getOutputStream()
	 */
	public abstract OutputStream getOutputStream();

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#isDirectory()
	 */
	public abstract boolean isDirectory();

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#isFile()
	 */
	public boolean isFile() {
		return !isDirectory();
	}

	
	public boolean isLink() {
		return false;
	}

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#link(java.net.URI)
	 */
	public boolean link(URI uri) {
		return false;
	}

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#list()
	 */
	public abstract String[] list();

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#mkdir()
	 */
	public abstract boolean mkdir();

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#move(java.net.URI)
	 */
	public abstract boolean move(URI uri);

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#setAttribute(java.lang.String, java.lang.Object)
	 */
	public boolean setAttribute(String name, Object value) {
		return false;
	}

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#setContent(java.lang.String)
	 */
	public boolean setContent(String s) {
		try {
			OutputStream out = getOutputStream();
			Writer w = new OutputStreamWriter(out);
			w.write(s);
			w.close();
			out.close();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#setContentEncoding(java.lang.String)
	 */
	public boolean setContentEncoding(String encoding) {
		return false;
	}

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#setContentType(java.lang.String)
	 */
	public boolean setContentType(String mimeType) {
		return false;
	}

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#setInputStream(java.io.InputStream)
	 */
	public boolean setInputStream(InputStream in) {
		try {
			OutputStream out = getOutputStream();
			byte buf[] = new byte[BUFSIZE];
			int len;
			while ((len = in.read(buf, 0, BUFSIZE)) != -1) {
				out.write(buf, 0, len);
			}
			in.close();
			out.close();
			return true;
		} catch (Exception e) {
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#setLastModified(long)
	 */
	public boolean setLastModified(long time) {
		return false;
	}

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#setLength(long)
	 */
	public boolean setLength(long len) {
		return false;
	}

	/* (non-Javadoc)
	 * @see jvs.vfs.IFile#setOutputStream(java.io.OutputStream)
	 */
	public boolean setOutputStream(OutputStream out) {
		try {
			java.io.InputStream in = getInputStream();
			byte buf[] = new byte[BUFSIZE];
			int len;
			while ((len = in.read(buf, 0, BUFSIZE)) != -1) {
				out.write(buf, 0, len);
			}
			in.close();
			out.close();
			return true;
		} catch (Exception e) {
		}
		return false;
	}
	
	public String getDisplayName() {
		return getName();
	}

	protected String getName() {
		String p = uri.getPath();
		if (p == null || p.equals("") || p.endsWith("/")) {
			return "";
		}
		int idx = p.lastIndexOf("/");
		if (idx == -1) {
			return p;
		}
		return p.substring(idx + 1);
	}
	
	protected String getParent() {
		String p = uri.getPath();
	
		if (p == null || p.equals("") || p.equals("/")) {
			return null;
		}
		if (p.endsWith("/")) {
			p = p.substring(0,p.length()-1);
		}
		int idx = p.lastIndexOf("/");
		if (idx == -1) {
			return null;
		}
		if (idx == 0) {
			return "/";
		}
		return p.substring(0,idx);
	}
	
	public void deleteOnExit() {
	}
	
	/*
	 * 
	 */

	protected void debug(Object o) {
			if (o instanceof Throwable) {
				Throwable t = (Throwable) o;
				t.printStackTrace();
				//Log.log(Log.TRACE,this,o);
				return;
			}
			Log.log(Log.DEBUG,this,o);
	}
	
	protected void trace(Object o) {
		if (o instanceof Throwable) {
			Throwable t = (Throwable) o;
			t.printStackTrace();
			//Log.log(Log.TRACE,this,o);
			return;
		}
		Log.log(Log.TRACE,this,o);
	}

	protected int count(InputStream in) throws IOException {
		int read = -1;
		byte[] b = new byte[BUFSIZE];
		int cnt = 0;
		while ((read = in.read(b)) != -1) {
			cnt += read;
		}
		return cnt;
	}
}
